﻿#region References
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Diagnostics;

using Autumoon.IPInformer.Fundamental;
using Autumoon.IPInformer.ModuleLayer;
#endregion

namespace Autumoon.IPInformer.ViewLayer
{
    public partial class MainForm : Form, IForm
    {
        #region Fields and Properties
        private static MainForm _instance = null;
        public static MainForm Instance
        {
            get { return ((_instance == null || _instance.IsDisposed) ? _instance = new MainForm() : _instance); }
        }

        private IPProperty _currentIPProperty = null;
        private InformOptionProperty _currentInformOption = null;
        private Timer _informTimer = null;
        #endregion

        #region Constructors
        public MainForm()
        {
            InitializeComponent();
        }
        #endregion

        #region Public Methods
        public void InitializeControl()
        {
            this.Text
                = this.notifyIcon.Text
                = String.Format("{0} V{1}{2}", Application.ProductName, Application.ProductVersion, (int.Parse(Application.ProductVersion.Split(new char[] { '.' })[0]) < 1 ? " - Beta" : String.Empty));
        }

        public void PropertyDataBinding()
        {
            this.InformOptionPropertyDataBinding();
        }
        #endregion

        #region Internal Methods
        #endregion

        #region Protected Methods
        #endregion

        #region Private Methods
        private void IPPropertDataBinding()
        {
            this.internalIPTextBox.Text
                = this.publicIPTextBox.Text
                = String.Empty;

            this._currentIPProperty = IPManager.GetIP(global::Autumoon.IPInformer.ViewLayer.Properties.Resources.IPCheckAddress);

            if (this._currentIPProperty != null)
            {
                this.internalIPTextBox.Text = this._currentIPProperty.InternalIP;
                this.publicIPTextBox.Text
                    = this.notifyIcon.Text
                    = this._currentIPProperty.PublicIP;
            }
        }

        private void InformOptionPropertyDataBinding()
        {
            this.receiverInboxTextBox.Text
                = this.smtpServerAddressTextBox.Text
                = this.userNameTextBox.Text
                = this.passwordTextBox.Text
                = this.senderOutboxTextBox.Text
                = String.Empty;

            this._currentInformOption = InformManager.GetInformOption();

            if (this._currentInformOption != null)
            {
                this.receiverInboxTextBox.Text = this._currentInformOption.ReceiverInbox;
                this.smtpServerAddressTextBox.Text = this._currentInformOption.SmtpServerAddress;
                this.userNameTextBox.Text = this._currentInformOption.UserName;
                this.passwordTextBox.Text = Utility.Decrypt(this._currentInformOption.EncryptedPassword);
                this.senderOutboxTextBox.Text = this._currentInformOption.SenderOutbox;
            }
        }

        private void InitializeInformTimer()
        {
            if (this._informTimer != null)
            {
                this._informTimer.Stop();
            }

            this._informTimer = new Timer();
            this._informTimer.Interval = 1000;
            this._informTimer.Tick += new EventHandler(this.informTimer_Tick);
            this._informTimer.Start();
        }

        private void SaveInformOption()
        {
            this._currentInformOption = new InformOptionProperty();
            this._currentInformOption.ReceiverInbox = this.receiverInboxTextBox.Text.Trim();
            this._currentInformOption.SmtpServerAddress = this.smtpServerAddressTextBox.Text.Trim();
            this._currentInformOption.UserName = this.userNameTextBox.Text.Trim();
            this._currentInformOption.EncryptedPassword = Utility.Encrypt(this.passwordTextBox.Text);
            this._currentInformOption.SenderOutbox = this.senderOutboxTextBox.Text.Trim();

            InformManager.Save(this._currentInformOption);
        }

        private void SetWindowState(FormWindowState formWindowState)
        {
            _instance.WindowState = formWindowState;

            if (WindowState == FormWindowState.Minimized)
            {
                _instance.ShowInTaskbar = false;
            }
            else
            {
                this.Show();
                this.Activate();

                _instance.ShowInTaskbar = true;
            }
        }

        private void ShowIP(IPProperty currentIP)
        {
            if (currentIP != null)
            {
                this.notifyIcon.ShowBalloonTip(5000, "IP", String.Format("Internal:\t{0}\nPublic:\t\t{1}", currentIP.InternalIP, currentIP.PublicIP), ToolTipIcon.Info);
            }
        }
        #endregion

        #region Delegates and Events
        private void MainForm_Load(object sender, EventArgs e)
        {
            try
            {
                this.InitializeControl();
                this.PropertyDataBinding();
                this.InitializeInformTimer();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, ex.Source, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void okButton_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.informCheckBox.Checked)
                {
                    this.SaveInformOption();

                    this._currentIPProperty = null;

                    this.InitializeInformTimer();
                }

                this.SetWindowState(FormWindowState.Minimized);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, ex.Source, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
            }
        }

        private void exitButton_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void informCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            this.informerOptionsGroupBox.Enabled = ((CheckBox)sender).Checked;
        }

        private void homePageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Process.Start(global::Autumoon.IPInformer.ViewLayer.Properties.Resources.HomePageAddress);
        }

        private void contactToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Process.Start(String.Format("mailto:{0}?Subject=About IP Informer", global::Autumoon.IPInformer.ViewLayer.Properties.Resources.ContactEmail));
        }

        private void informTimer_Tick(object sender, EventArgs e)
        {
            this._informTimer.Interval = 5 * 60 * 1000;

            try
            {
                IPProperty currentIP = IPManager.GetIP(global::Autumoon.IPInformer.ViewLayer.Properties.Resources.IPCheckAddress);

                if (InformManager.Inform(this._currentIPProperty, currentIP, this._currentInformOption))
                {
                    this.IPPropertDataBinding();
                    this.ShowIP(currentIP);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, ex.Source, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
            }
        }

        private void MainForm_SizeChanged(object sender, EventArgs e)
        {
        }

        private void notifyIcon_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                this.notifyContextMenuStrip.Show(Control.MousePosition);
            }
            else if (e.Button == MouseButtons.Left)
            {
                this.ShowIP(this._currentIPProperty);
            }
        }

        private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                this.SetWindowState(FormWindowState.Normal);
            }
        }

        private void openContextToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.SetWindowState(FormWindowState.Normal);
        }

        private void exitContextToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new AboutForm().ShowDialog();
        }
        #endregion
    }
}